<!DOCTYPE html>
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >

 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Functional core of Objective CAML
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora014.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora016.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Functional core of Objective CAML</H2>
Like all functional languages, Objective CAML is an expression oriented language,
where programming consists mainly of creating functions and applying them. 
The result of the evaluation of one of these expressions is a value in the 
language and the execution of a program is the evaluation of all the 
expressions which comprise it.<BR>
<BR>
<A NAME="toc8"></A>
<H3> Primitive values, functions, and types</H3>
Integers and floating-point numbers, characters, character strings, and
booleans are predefined in Objective CAML.<BR>
<BR>

<H4> Numbers</H4>
<A NAME="@fonctions0"></A><A NAME="@fonctions1"></A><A NAME="@concepts6"></A><A NAME="@concepts7"></A>There are two kinds of numbers: integers<A NAME="text3" HREF="book-ora023.html#note3"><SUP><FONT SIZE=2>1</FONT></SUP></A> of type <I>int</I> and
floating-point numbers of type <I>float</I>. Objective CAML follows the IEEE
754 standard<A NAME="text4" HREF="book-ora023.html#note4"><SUP><FONT SIZE=2>2</FONT></SUP></A> for representing double-precision floating-point numbers.
The operations on integers and floating-point numbers are described in
figure <A HREF="book-ora015.html#fig-operations">2.1</A>. Let us note that when the result of an integer
operation is outside the interval on which values of type
<I>int</I> are defined, this does not produce an error, but the result is an integer
within the system's interval of integers. In other words, all integer
operations are operations <EM>modulo</EM> the boundaries of the interval.
<A NAME="@fonctions2"></A><A NAME="@fonctions3"></A><A NAME="@fonctions4"></A><A NAME="@fonctions5"></A><A NAME="@fonctions6"></A><A NAME="@fonctions7"></A><A NAME="@fonctions8"></A><A NAME="@fonctions9"></A><A NAME="@fonctions10"></A><A NAME="@fonctions11"></A><BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>integer numbers</TD>
<TD  ALIGN=left NOWRAP>floating-point numbers</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=right NOWRAP><TT>+</TT></TD>
<TD  ALIGN=left NOWRAP>addition</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP><TT>-</TT></TD>
<TD  ALIGN=left NOWRAP>subtraction and unary negation</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP><TT>*</TT></TD>
<TD  ALIGN=left NOWRAP>multiplication</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP><TT>/</TT></TD>
<TD  ALIGN=left NOWRAP>integer division</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP><TT>mod</TT></TD>
<TD  ALIGN=left NOWRAP>remainder of integer division</TD>
</TR></TABLE>
</TD>
<TD  ALIGN=left NOWRAP>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><TT>+.</TT></TD>
<TD  ALIGN=left NOWRAP>addition</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>-.</TT></TD>
<TD  ALIGN=left NOWRAP>subtraction and unary negation</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>*.</TT></TD>
<TD  ALIGN=left NOWRAP>multiplication</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>/.</TT></TD>
<TD  ALIGN=left NOWRAP>division</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>**</TT></TD>
<TD  ALIGN=left NOWRAP>exponentiation</TD>
</TR></TABLE></TD>
</TR></TABLE>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>


<PRE><BR># <CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : int = 1</CODE><BR># <CODE>1</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>- : int = 3</CODE><BR># <CODE>9</CODE><CODE> </CODE><CODE>/</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>- : int = 4</CODE><BR># <CODE>1</CODE><CODE>1</CODE><CODE> </CODE><B>mod</B><CODE> </CODE><CODE>3</CODE><CODE> </CODE>;;<BR><CODE>- : int = 2</CODE><BR><CODE>(* limits of the representation  *)</CODE><BR><CODE>(* of integers                   *)</CODE><BR># <CODE>2</CODE><CODE>1</CODE><CODE>4</CODE><CODE>7</CODE><CODE>4</CODE><CODE>8</CODE><CODE>3</CODE><CODE>6</CODE><CODE>5</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : int = 2</CODE><BR>

</PRE>

&nbsp;
</TD>
<TD  ALIGN=left NOWRAP>


<PRE><BR># <CODE>2</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : float = 2</CODE><BR># <CODE>1</CODE><CODE>.</CODE><CODE>1</CODE><CODE> </CODE><CODE>+.</CODE><CODE> </CODE><CODE>2</CODE><CODE>.</CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>- : float = 3.3</CODE><BR># <CODE>9</CODE><CODE>.</CODE><CODE>1</CODE><CODE> </CODE><CODE>/.</CODE><CODE> </CODE><CODE>2</CODE><CODE>.</CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>- : float = 4.13636363636</CODE><BR># <CODE>1</CODE><CODE>.</CODE><CODE> </CODE><CODE>/.</CODE><CODE> </CODE><CODE>0</CODE><CODE>.</CODE><CODE> </CODE>;;<BR><CODE>- : float = inf</CODE><BR><CODE>(* limits of the representation  *)</CODE><BR><CODE>(* of floating-point numbers     *)</CODE><BR># <CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>2</CODE><CODE>.</CODE><CODE>1</CODE><CODE>1</CODE><CODE>1</CODE><CODE>1</CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : float = 222222222222</CODE><BR>

</PRE>

&nbsp;</TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 2.1: Operations on numbers.</DIV><BR>

<A NAME="fig-operations"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>
<H5> Differences between integers and floating-point numbers</H5>
Values having different types such as <I>float</I> and <I>int</I>
can never be compared directly. But there are functions for conversion
(<TT>float_of_int</TT> and <TT>int_of_float</TT>) between one and the
other.


<PRE><BR># <CODE>2</CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>Characters 5-8:</CODE><BR><CODE>This expression has type float but is here used with type int</CODE><BR># <CODE>3</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE>float_of_int<CODE> </CODE><CODE>3</CODE><CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR>

</PRE>
<BR>
<BR>
In the same way, operations on floating-point numbers are distinct from
those on integers.<BR>
<BR>


<PRE><BR># <CODE>3</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>- : int = 5</CODE><BR># <CODE>3</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><CODE>+.</CODE><CODE> </CODE><CODE>2</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : float = 5</CODE><BR># <CODE>3</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>Characters 0-3:</CODE><BR><CODE>This expression has type float but is here used with type int</CODE><BR># sin<CODE> </CODE><CODE>3</CODE><CODE>.</CODE><CODE>1</CODE><CODE>4</CODE><CODE>1</CODE><CODE>5</CODE><CODE>9</CODE><CODE> </CODE>;;<BR><CODE>- : float = 2.65358979335e-06</CODE><BR>

</PRE>
<BR>
<BR>
An ill-defined computation, such as a division by zero, will raise an
exception (see page <A HREF="book-ora017.html#sec-exceptions">??</A>) which interrupts the
computation. Floating-point numbers have a representation for infinite
values (printed as <TT>Inf</TT>) and ill-defined computations (printed as
<TT>NaN</TT><A NAME="text5" HREF="book-ora023.html#note5"><SUP><FONT SIZE=2>3</FONT></SUP></A>). The main functions on
floating-point numbers are described in figure <A HREF="book-ora015.html#fig-floatfn">2.2</A>.<BR>
<BR>
<A NAME="@fonctions12"></A>
<A NAME="@fonctions13"></A>
<A NAME="@fonctions14"></A>
<A NAME="@fonctions15"></A>
<A NAME="@fonctions16"></A>
<A NAME="@fonctions17"></A>
<A NAME="@fonctions18"></A>
<A NAME="@fonctions19"></A>
<A NAME="@fonctions20"></A>
<A NAME="@fonctions21"></A>
<A NAME="@fonctions22"></A>
<A NAME="@fonctions23"></A><BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>functions on floats</TD>
<TD  ALIGN=left NOWRAP>trigonometric functions</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><TT>ceil</TT></TD>
<TD  ALIGN=left NOWRAP>&nbsp;</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>floor</TT></TD>
<TD  ALIGN=left NOWRAP>&nbsp;</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>sqrt</TT></TD>
<TD  ALIGN=left NOWRAP>square root</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>exp</TT></TD>
<TD  ALIGN=left NOWRAP>exponential</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>log</TT></TD>
<TD  ALIGN=left NOWRAP>natural log</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>log10</TT></TD>
<TD  ALIGN=left NOWRAP>log base 10</TD>
</TR></TABLE>
</TD>
<TD  ALIGN=left NOWRAP>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><TT>cos</TT></TD>
<TD  ALIGN=left NOWRAP>cosine</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>sin</TT></TD>
<TD  ALIGN=left NOWRAP>sine</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>tan</TT></TD>
<TD  ALIGN=left NOWRAP>tangent</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>acos</TT></TD>
<TD  ALIGN=left NOWRAP>arccosine</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>asin</TT></TD>
<TD  ALIGN=left NOWRAP>arcsine</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>atan</TT></TD>
<TD  ALIGN=left NOWRAP>arctangent</TD>
</TR></TABLE></TD>
</TR></TABLE>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>


<PRE><BR># ceil<CODE> </CODE><CODE>3</CODE><CODE>.</CODE><CODE>4</CODE><CODE> </CODE>;;<BR><CODE>- : float = 4</CODE><BR># floor<CODE> </CODE><CODE>3</CODE><CODE>.</CODE><CODE>4</CODE><CODE> </CODE>;;<BR><CODE>- : float = 3</CODE><BR># ceil<CODE> </CODE><TT>(</TT><CODE>-.</CODE><CODE>3</CODE><CODE>.</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : float = -3</CODE><BR># floor<CODE> </CODE><TT>(</TT><CODE>-.</CODE><CODE>3</CODE><CODE>.</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : float = -4</CODE><BR>

</PRE>

&nbsp; 
</TD>
<TD  ALIGN=left NOWRAP>


<PRE><BR># sin<CODE> </CODE><CODE>1</CODE><CODE>.</CODE><CODE>5</CODE><CODE>7</CODE><CODE>0</CODE><CODE>7</CODE><CODE>8</CODE><CODE> </CODE>;;<BR><CODE>- : float = 0.999999999867</CODE><BR># sin<CODE> </CODE><TT>(</TT>asin<CODE> </CODE><CODE>0</CODE><CODE>.</CODE><CODE>7</CODE><CODE>0</CODE><CODE>7</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : float = 0.707</CODE><BR># acos<CODE> </CODE><CODE>0</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : float = 1.57079632679</CODE><BR># asin<CODE> </CODE><CODE>3</CODE><CODE>.</CODE><CODE>1</CODE><CODE>4</CODE><CODE> </CODE>;;<BR><CODE>- : float = nan</CODE><BR>

</PRE>

&nbsp;</TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 2.2: Functions on floats.</DIV><BR>

<A NAME="fig-floatfn"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>
<H4> Characters and Strings</H4>
<A NAME="@concepts8"></A>
<A NAME="@concepts9"></A>
<A NAME="@concepts10"></A>
<A NAME="@fonctions24"></A><A NAME="@fonctions25"></A>Characters, type <I>char</I>, correspond to integers between 0 and 255
inclusive, following the ASCII encoding for the first 128. The functions
<TT>char_of_int</TT> and <TT>int_of_char</TT> support conversion
between integers and characters.
<A NAME="@fonctions26"></A>
<A NAME="@fonctions27"></A>
Character strings, type <I>string</I>, are sequences of characters of
definite length (less than 2<SUP><FONT SIZE=2>24</FONT></SUP>-6). The concatenation operator is
<TT>&nbsp;</TT>.
<A NAME="@fonctions28"></A>
The functions <TT>int_of_string</TT>, <TT>string_of_int</TT>,
<TT>string_of_float</TT> and <TT>float_of_string</TT> carry out the
various conversions between numbers and character strings.
<A NAME="@fonctions29"></A>
<A NAME="@fonctions30"></A>
<A NAME="@fonctions31"></A>
<A NAME="@fonctions32"></A>


<PRE><BR># <CODE>'B'</CODE><CODE> </CODE>;;<BR><CODE>- : char = 'B'</CODE><BR># int_of_char<CODE> </CODE><CODE>'B'</CODE><CODE> </CODE>;;<BR><CODE>- : int = 66</CODE><BR># <CODE>"is a string"</CODE><CODE> </CODE>;;<BR><CODE>- : string = "is a string"</CODE><BR># <TT>(</TT>string_of_int<CODE> </CODE><CODE>1</CODE><CODE>9</CODE><CODE>8</CODE><CODE>7</CODE><TT>)</TT><CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>" is the year Caml was created"</CODE><CODE> </CODE>;;<BR><CODE>- : string = "1987 is the year Caml was created"</CODE><BR>

</PRE>
<BR>
<BR>
Even if a string contains the characters of a number, it won't be possible
to use it in operations on numbers without carrying out an explicit
conversion.


<PRE><BR># <CODE>"1999"</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>Characters 1-7:</CODE><BR><CODE>This expression has type string but is here used with type int</CODE><BR># <TT>(</TT>int_of_string<CODE> </CODE><CODE>"1999"</CODE><TT>)</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : int = 2000</CODE><BR>

</PRE>

Numerous functions on character strings are gathered in the
<TT>String</TT> module (see page <A HREF="book-ora076.html#sec-mod-string">??</A>).<BR>
<BR>

<H4> Booleans</H4>
<A NAME="@fonctions33"></A><A NAME="@concepts11"></A>Booleans, of type <I>bool</I>, belong to a set consisting of two values: 
<TT>true</TT> and <TT>false</TT>. The primitive operators are described in 
figure
<A HREF="book-ora015.html#fig-bool">2.3</A>. For historical reasons, the ``and'' and ``or'' operators
each have two forms.
<A NAME="@fonctions34"></A>
<A NAME="@fonctions35"></A>
<A NAME="@fonctions36"></A>
<A NAME="@fonctions37"></A>
<A NAME="@fonctions38"></A>
<A NAME="@fonctions39"></A>
<A NAME="@fonctions40"></A>
<A NAME="@fonctions41"></A>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=right NOWRAP><TT>not</TT></TD>
<TD  ALIGN=left NOWRAP>negation</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP><TT>&amp;&amp;</TT></TD>
<TD  ALIGN=left NOWRAP>sequential and</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP><TT>||</TT></TD>
<TD  ALIGN=left NOWRAP>sequential or</TD>
</TR></TABLE>
</TD>
<TD  ALIGN=left NOWRAP>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
</TR>
<TR><TD  ALIGN=right NOWRAP><TT>&amp;</TT></TD>
<TD  ALIGN=left NOWRAP>synonym for <TT>&amp;&amp;</TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP><TT>or</TT></TD>
<TD  ALIGN=left NOWRAP>synonym for <TT>||</TT></TD>
</TR>
<TR><TD  ALIGN=right NOWRAP>&nbsp;</TD>
</TR></TABLE></TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 2.3: Operators on booleans.</DIV><BR>

<A NAME="fig-bool"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>


<PRE><BR># <B>true</B><CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR># not<CODE> </CODE><B>true</B><CODE> </CODE>;;<BR><CODE>- : bool = false</CODE><BR># <B>true</B><CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><B>false</B><CODE> </CODE>;;<BR><CODE>- : bool = false</CODE><BR>

</PRE>

The operators <TT>&amp;&amp;</TT> and <TT>||</TT>, or their synonyms,
evaluate their left argument and then, depending on its value, evaluate
their right argument. They can be rewritten in the form of conditional
constructs (see page <A HREF="book-ora015.html#subsec-cond">??</A>).<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><TT>=</TT></TD>
<TD  ALIGN=left NOWRAP>structural equality</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>==</TT></TD>
<TD  ALIGN=left NOWRAP>physical equality</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>&lt;&gt;</TT></TD>
<TD  ALIGN=left NOWRAP>negation of <TT>=</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>!=</TT></TD>
<TD  ALIGN=left NOWRAP>negation of <TT>==</TT></TD>
</TR></TABLE>
</TD>
<TD  ALIGN=left NOWRAP>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><TT>&lt;</TT></TD>
<TD  ALIGN=left NOWRAP>less than</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>&gt;</TT></TD>
<TD  ALIGN=left NOWRAP>greater than</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>&lt;=</TT></TD>
<TD  ALIGN=left NOWRAP>less than or equal to</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>&gt;=</TT></TD>
<TD  ALIGN=left NOWRAP>greater than or equal to</TD>
</TR></TABLE></TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 2.4: Equality and comparison operators.</DIV><BR>

<A NAME="fig-comp"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE><A NAME="@fonctions42"></A><A NAME="@fonctions43"></A><A NAME="@fonctions44"></A><A NAME="@fonctions45"></A><A NAME="@fonctions46"></A><A NAME="@fonctions47"></A><A NAME="@fonctions48"></A>The
equality and comparison operators are described in figure
<A HREF="book-ora015.html#fig-comp">2.4</A>.
They are polymorphic, i.e., they can be used to compare two integers as
well as two character strings. The only constraint is that their two
operands must be of the same type (see page <A HREF="book-ora015.html#subsec-poly">??</A>).


<PRE><BR># <CODE>1</CODE><CODE>&lt;=</CODE><CODE>1</CODE><CODE>1</CODE><CODE>8</CODE><CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>=</CODE><CODE>2</CODE><CODE> </CODE><CODE>||</CODE><CODE> </CODE>not<TT>(</TT><CODE>1</CODE><CODE>=</CODE><CODE>2</CODE><TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR># <CODE>1</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><CODE>&lt;=</CODE><CODE> </CODE><CODE>1</CODE><CODE>1</CODE><CODE>8</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><CODE>||</CODE><CODE> </CODE>not<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>.</CODE><CODE>0</CODE><TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR># <CODE>"one"</CODE><CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><CODE>"two"</CODE><CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR># <CODE>0</CODE><CODE> </CODE><CODE>&lt;</CODE><CODE> </CODE><CODE>'0'</CODE><CODE> </CODE>;;<BR><CODE>Characters 4-7:</CODE><BR><CODE>This expression has type char but is here used with type int</CODE><BR>

</PRE>
<BR>
<BR>
Structural equality tests the equality of two values by traversing their
structure, whereas physical equality tests whether the two values occupy
the same region in memory. These two equality operators return the same
result for simple values: booleans, characters, integers and constant
constructors (page <A HREF="book-ora016.html#subsec-typ-somme">??</A>).


<H3> Warning </H3> <HR>

Floating-point numbers and character strings are considered structured
values.


<HR>

<BR>
<BR>

<H4> Unit</H4>
<A NAME="@fonctions49"></A><A NAME="@fonctions50"></A>The <I>unit</I> type describes a set which possesses only a single
element, denoted: <TT>()</TT>. 


<PRE><BR># ()<CODE> </CODE>;;<BR><CODE>- : unit = ()</CODE><BR>

</PRE>

This value will often be used in imperative programs
(<A HREF="index.html#chap-PI">3</A>, page <A HREF="index.html#chap-PI">??</A>) for functions which carry out
side effects. Functions whose result is the value <TT>()</TT> simulate the
notion of procedure, which doesn't exist in Objective CAML, just as the type <TT>void</TT> does in the C language.<BR>
<BR>

<H4> Cartesian product, tuple</H4>
<A NAME="@concepts12"></A>
<A NAME="@concepts13"></A>
<A NAME="@concepts14"></A>
<A NAME="@fonctions51"></A>Values of possibly different types can be gathered in pairs or more generally in
tuples. The values making up a tuple are separated by commas. The type
constructor <I>*</I> indicates a tuple. The type <I>int * string</I>
is the type of pairs whose first element is an integer (of type
<I>int</I>) and whose second is a character string (of type
<I>string</I>).


<PRE><BR># <TT>(</TT><CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE> </CODE><CODE>,</CODE><CODE> </CODE><CODE>"October"</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : int * string = 12, "October"</CODE><BR>

</PRE>

When there is no ambiguity, it can be written more simply:


<PRE><BR># <CODE>1</CODE><CODE>2</CODE><CODE> </CODE><CODE>,</CODE><CODE> </CODE><CODE>"October"</CODE><CODE> </CODE>;;<BR><CODE>- : int * string = 12, "October"</CODE><BR>

</PRE>

The functions <TT>fst</TT> and <TT>snd</TT> allow access to the first and
second elements of a pair.
<A NAME="@fonctions52"></A>
<A NAME="@fonctions53"></A>


<PRE><BR># fst<CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE> </CODE><CODE>,</CODE><CODE> </CODE><CODE>"October"</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : int = 12</CODE><BR># snd<CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE> </CODE><CODE>,</CODE><CODE> </CODE><CODE>"October"</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : string = "October"</CODE><BR>

</PRE>

These two functions accept pairs whose components are of any type
whatsoever. They are polymorphic, in the same way as equality.


<PRE><BR># fst;;<BR><CODE>- : 'a * 'b -&gt; 'a = &lt;fun&gt;</CODE><BR># fst<CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>"October"</CODE><CODE>,</CODE><CODE> </CODE><CODE>1</CODE><CODE>2</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : string = "October"</CODE><BR>

</PRE>

The type <I>int * char * string</I> is that of triplets whose first element
is of type <I>int</I>, whose second is of type <I>char</I>, and whose third
is of type <I>string</I>. Its values are written


<PRE><BR># <TT>(</TT><CODE> </CODE><CODE>6</CODE><CODE>5</CODE><CODE> </CODE><CODE>,</CODE><CODE> </CODE><CODE>'B'</CODE><CODE> </CODE><CODE>,</CODE><CODE> </CODE><CODE>"ascii"</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : int * char * string = 65, 'B', "ascii"</CODE><BR>

</PRE>
<BR>
<BR>


<H3> Warning </H3> <HR>

The functions <TT>fst</TT> and <TT>snd</TT>
applied to a tuple, other than a pair, result in a type error.


<HR>




<PRE><BR># snd<CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>6</CODE><CODE>5</CODE><CODE> </CODE><CODE>,</CODE><CODE> </CODE><CODE>'B'</CODE><CODE> </CODE><CODE>,</CODE><CODE> </CODE><CODE>"ascii"</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>Characters 7-25:</CODE><BR><CODE>This expression has type int * char * string but is here used with type</CODE><BR><CODE>  'a * 'b</CODE><BR>

</PRE>

There is indeed a difference between the type of a pair and that of a
triplet. The type <I>int * int * int</I> is different from the types
<I>(int * int) * int</I> and <I>int * (int * int)</I>. Functions to
access a triplet (and other tuples) are not defined by the core library.
One can use pattern matching to define them if need be (see page
<A HREF="book-ora016.html#subsec-filtrage">??</A>). <BR>
<BR>

<H4> Lists</H4>
<A NAME="@fonctions54"></A><A NAME="@concepts15"></A>Values of the same type can be gathered into a list. A list can either be
empty or consist of elements of the same type.
<A NAME="@fonctions55"></A>

<PRE><BR># []<CODE> </CODE>;;<BR><CODE>- : 'a list = []</CODE><BR># <CODE>[</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<CODE> </CODE><CODE>2</CODE><CODE> </CODE>;<CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int list = [1; 2; 3]</CODE><BR># <CODE>[</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<CODE> </CODE><CODE>"two"</CODE><CODE> </CODE>;<CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>Characters 14-17:</CODE><BR><CODE>This expression has type int list but is here used with type string list</CODE><BR>

</PRE>
<BR>
<BR>
The function which adds an element at the head of a list is the infix
operator :: . It is the analogue of Lisp's <EM>cons</EM>.
<A NAME="@fonctions56"></A>

<PRE><BR># <CODE>1</CODE><CODE> </CODE>::<CODE> </CODE><CODE>2</CODE><CODE> </CODE>::<CODE> </CODE><CODE>3</CODE><CODE> </CODE>::<CODE> </CODE>[]<CODE> </CODE>;;<BR><CODE>- : int list = [1; 2; 3]</CODE><BR>

</PRE>
<BR>
<BR>
Concatenation of two lists is also an infix operator <TT>@</TT>. 
<A NAME="@fonctions57"></A>


<PRE><BR># <CODE>[</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE><CODE> </CODE><CODE>@</CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>;<CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int list = [1; 2; 3]</CODE><BR># <CODE>[</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<CODE> </CODE><CODE>2</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE><CODE> </CODE><CODE>@</CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int list = [1; 2; 3]</CODE><BR>

</PRE>
<BR>
<BR>
The other list manipulation functions are defined in the <TT>List</TT>
library. The functions <TT>hd</TT> and <TT>tl</TT> from this library give
respectively the head and the tail of a list when these values exist.
These functions are denoted by <TT>List.hd</TT> and <TT>List.tl</TT> to
indicate to the system that they can be found in the module
<TT>List</TT><A NAME="text6" HREF="book-ora023.html#note6"><SUP><FONT SIZE=2>4</FONT></SUP></A>. 
<A NAME="@fonctions58"></A>
<A NAME="@fonctions59"></A>
<A NAME="@fonctions60"></A>


<PRE><BR># List.hd<CODE> </CODE><CODE>[</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;<CODE> </CODE><CODE>2</CODE><CODE> </CODE>;<CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int = 1</CODE><BR># List.hd<CODE> </CODE>[]<CODE> </CODE>;;<BR><CODE>Uncaught exception: Failure("hd")</CODE><BR>

</PRE>

In this last example, it is indeed problematic to request retrieval of the
first element of an empty list. It is for this reason that the system
raises an exception (see page <A HREF="book-ora017.html#sec-exceptions">??</A>). <BR>
<BR>
<A NAME="toc9"></A>
<H3> Conditional control structure</H3>
<A NAME="subsec-cond"></A>
<A NAME="@fonctions61"></A><A NAME="@fonctions62"></A><A NAME="@fonctions63"></A><A NAME="@concepts16"></A>
One of the indispensable control structures in any programming language is
the structure called conditional (or branch) which guides the
computation as a function of a condition. <BR>
<BR>


<H3> Syntax </H3> <HR>


<B>if</B> <I>expr</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>then</B> <I>expr</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB> <B>else</B>
<I>expr</I><SUB><I><FONT SIZE=2>3</FONT></I></SUB> 



<HR>


The expression <I>expr</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> is of type <I>bool</I>. The expressions
<I>expr</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB> and <I>expr</I><SUB><I><FONT SIZE=2>3</FONT></I></SUB> must be of the same type, whatever it
may be.<BR>
<BR>


<PRE><BR># <B>if</B><CODE> </CODE><CODE>3</CODE><CODE>=</CODE><CODE>4</CODE><CODE> </CODE><B>then</B><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>4</CODE><CODE> </CODE>;;<BR><CODE>- : int = 4</CODE><BR># <B>if</B><CODE> </CODE><CODE>3</CODE><CODE>=</CODE><CODE>4</CODE><CODE> </CODE><B>then</B><CODE> </CODE><CODE>"0"</CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>"4"</CODE><CODE> </CODE>;;<BR><CODE>- : string = "4"</CODE><BR># <B>if</B><CODE> </CODE><CODE>3</CODE><CODE>=</CODE><CODE>4</CODE><CODE> </CODE><B>then</B><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE> </CODE><CODE>"4"</CODE>;;<BR><CODE>Characters 20-23:</CODE><BR><CODE>This expression has type string but is here used with type int</CODE><BR>

</PRE>
<BR>
<BR>
A conditional construct is itself an expression and its evaluation
returns a value.<BR>
<BR>


<PRE><BR># <TT>(</TT><B>if</B><CODE> </CODE><CODE>3</CODE><CODE>=</CODE><CODE>5</CODE><CODE> </CODE><B>then</B><CODE> </CODE><CODE>8</CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>- : int = 15</CODE><BR>

</PRE>
<BR>
<BR>


<H3> Note </H3> <HR>

The <B>else</B> branch can be omitted, but in this case it is implicitly
replaced by <B>else</B><CODE> </CODE>(). Consequently, the type of the expression
<I>expr</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB> must be <I>unit</I> (see page <A HREF="book-ora028.html#ex-if-then">??</A>). 


<HR>

<BR>
<BR>
<A NAME="toc10"></A>
<H3> Value declarations</H3>
<A NAME="@concepts17"></A><A NAME="@concepts18"></A>
<A NAME="@concepts19"></A>
<A NAME="@concepts20"></A>
A declaration binds a name to a value. There are two types: global
declarations and local declarations. In the first case, the
declared names are known to all the expressions following the declaration;
in the second, the declared names are only known to one expression. It is
equally possible to <EM>simultaneously</EM> declare several name-value
bindings.<BR>
<BR>

<H4> Global declarations</H4>
<A NAME="@concepts21"></A><A NAME="@fonctions64"></A>


<H3> Syntax </H3> <HR>


 <B>let</B> <I>name</I> <B>=</B> <I>expr</I> <B>;;</B>



<HR>


A global declaration defines the binding between the name <I>name</I> and
the value of the expression <I>expr</I> which will be known to all
subsequent expressions.


<PRE><BR># <B>let</B><CODE> </CODE>yr<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"1999"</CODE><CODE> </CODE>;;<BR><CODE>val yr : string = "1999"</CODE><BR># <B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>int_of_string<TT>(</TT>yr<TT>)</TT><CODE> </CODE>;;<BR><CODE>val x : int = 1999</CODE><BR># x<CODE> </CODE>;;<BR><CODE>- : int = 1999</CODE><BR># x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : int = 2000</CODE><BR># <B>let</B><CODE> </CODE>new_yr<CODE> </CODE><CODE>=</CODE><CODE> </CODE>string_of_int<CODE> </CODE><TT>(</TT>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val new_yr : string = "2000"</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Simultaneous global declarations</H4>
<A NAME="@concepts22"></A><A NAME="@fonctions65"></A>


<H3> Syntax </H3> <HR>


<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><B>let</B> <I>name</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>=</B> <I>expr</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>and</B> <I>name</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB> <B>=</B> <I>expr</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>:</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>and</B> <I>name</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> <B>=</B> <I>expr</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> <B>;;</B></TD>
</TR></TABLE>



<HR>

<BR>
<BR>
A simultaneous declaration declares different symbols at the same level.
They won't be known until the end of all the declarations.


<PRE><BR># <B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE><B>and</B><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>val x : int = 1</CODE><BR><CODE>val y : int = 2</CODE><BR># x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<CODE> </CODE>;;<BR><CODE>- : int = 3</CODE><BR># <B>let</B><CODE> </CODE>z<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><B>and</B><CODE> </CODE>t<CODE> </CODE><CODE>=</CODE><CODE> </CODE>z<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>;;<CODE> </CODE><BR><CODE>Characters 18-19:</CODE><BR><CODE>Unbound value z</CODE><BR>

</PRE>
<BR>
<BR>
It is possible to gather several global declarations in the same phrase;
then printing of their types and their values does not take place until the
end of the phrase, marked by double ``<B>;;</B>''.
These declarations are evaluated sequentially, in contrast with a simultaneous
declaration.


<PRE><BR># <B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE><BR><CODE> </CODE><B>let</B><CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE> </CODE>;;<BR><CODE>val x : int = 2</CODE><BR><CODE>val y : int = 5</CODE><BR>

</PRE>

A global declaration can be masked by a new declaration of the same name
(see page <A HREF="book-ora015.html#subsubsec-portee">??</A>).<BR>
<BR>

<H4> Local declarations</H4>
<A NAME="@concepts23"></A><A NAME="@fonctions66"></A><A NAME="@fonctions67"></A>


<H3> Syntax </H3> <HR>


 <B>let</B> <I>name</I> <B>=</B> <I>expr</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>in</B> 
<I>expr</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB><B>;;</B> 



<HR>


The name <I>name</I> is only known during the evaluation of
<I>expr</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB>. The local declaration
binds it to the value of <I>expr</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB>. 


<PRE><BR># <B>let</B><CODE> </CODE>xl<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><B>in</B><CODE> </CODE>xl<CODE> </CODE><CODE>*</CODE><CODE> </CODE>xl<CODE> </CODE>;;<BR><CODE>- : int = 9</CODE><BR>

</PRE>

The local declaration binding <TT>xl</TT> to the value <TT>3</TT> is only
in effect during the evaluation of xl<CODE> </CODE><CODE>*</CODE><CODE> </CODE>xl. 


<PRE><BR># xl<CODE> </CODE>;;<BR><CODE>Characters 1-3:</CODE><BR><CODE>Unbound value xl</CODE><BR>

</PRE>

A local declaration masks all previous declarations of the same name, but
the previous value is reinstated upon leaving the scope of the local
declaration:


<PRE><BR># <B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>val x : int = 2</CODE><BR># <B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><B>in</B><CODE> </CODE>x<CODE> </CODE><CODE>*</CODE><CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>- : int = 9</CODE><BR># x<CODE> </CODE><CODE>*</CODE><CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>- : int = 4</CODE><BR>

</PRE>

A local declaration is an expression and can thus be used to construct
other expressions:


<PRE><BR># <TT>(</TT><B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE><B>in</B><CODE> </CODE>x<CODE> </CODE><CODE>*</CODE><CODE> </CODE>x<TT>)</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : int = 10</CODE><BR>

</PRE>
<BR>
<BR>
Local declarations can also be simultaneous.
<A NAME="@concepts24"></A>

<H3> Syntax </H3> <HR>

<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP><B>let</B></TD>
<TD  ALIGN=left NOWRAP><I>name</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> <B>=</B> <I>expr</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>and</B></TD>
<TD  ALIGN=left NOWRAP><I>name</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB> <B>=</B> <I>expr</I><SUB><I><FONT SIZE=2>2</FONT></I></SUB></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>:</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>and</B></TD>
<TD  ALIGN=left NOWRAP><I>name</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> <B>=</B> <I>expr</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><B>in</B></TD>
<TD  ALIGN=left NOWRAP><I>expr</I> <B>;;</B></TD>
</TR></TABLE>



<HR>

<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>3</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><B>and</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>4</CODE><CODE>.</CODE><CODE>0</CODE><CODE> </CODE><B>in</B><CODE> </CODE>sqrt<CODE> </CODE><TT>(</TT>a<CODE>*.</CODE>a<CODE> </CODE><CODE>+.</CODE><CODE> </CODE>b<CODE>*.</CODE>b<TT>)</TT><CODE> </CODE>;;<BR><CODE>- : float = 5</CODE><BR># b<CODE> </CODE>;;<BR><CODE>Characters 0-1:</CODE><BR><CODE>Unbound value b</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc11"></A>
<H3> Function expressions, functions</H3>
<A NAME="@concepts25"></A><A NAME="@concepts26"></A>
<A NAME="@concepts27"></A>
<A NAME="@concepts28"></A>
<A NAME="@concepts29"></A>
<A NAME="@fonctions68"></A>
<A NAME="@fonctions69"></A> 
A function expression consists of a <EM>parameter</EM> and
a <EM>body</EM>. The formal parameter is a variable name and the body an
expression. The parameter is said to be abstract. For this reason,
a function expression is also called an abstraction.


<H3> Syntax </H3> <HR>


<B>function</B> <I>p</I>  -&gt; expr



<HR>


Thus the function which squares its argument is written:


<PRE><BR># <B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE>*</CODE>x<CODE> </CODE>;;<BR><CODE>- : int -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>

The Objective CAML system deduces its type. The function type
<I>int -&gt; int</I> indicates a function expecting a parameter of 
type <I>int</I> and returning a value of type <I>int</I>.<BR>
<BR>
<A NAME="@concepts30"></A>
<A NAME="@concepts31"></A>
Application of a function to an argument is written as the function
followed by the argument.
<A NAME="@concepts32"></A>

<PRE><BR># <TT>(</TT><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><CODE>*</CODE><CODE> </CODE>x<TT>)</TT><CODE> </CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>- : int = 25</CODE><BR>

</PRE>

The evaluation of an application amounts to evaluating the body of the
function, here x<CODE> </CODE><CODE>*</CODE><CODE> </CODE>x, where the
formal parameter, <TT>x</TT>, is replaced by the value of the argument (or
the actual parameter), here <CODE>5</CODE>.<BR>
<BR>
In the construction of a function expression, expr is any
expression whatsoever. In particular, expr may itself be a
function expression.<BR>
<BR>


<PRE><BR># <B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<TT>)</TT><CODE> </CODE>;;<BR><CODE>- : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The parentheses are not required. One can write more simply:


<PRE><BR># <B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<CODE> </CODE>;;<BR><CODE>- : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>

The type of this expression can be read in the usual way as the type of a
function which expects two integers and returns an integer value. But in
the context of a functional language such as Objective CAML we are dealing
more precisely with the type of a function which expects an integer and
returns a function value of type
<I>int -&gt; int</I>: 


<PRE><BR># <TT>(</TT><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<TT>)</TT><CODE> </CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>- : int -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
One can, of course, use the function expression in the usual way by
applying it to two arguments. One writes:


<PRE><BR># <TT>(</TT><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<TT>)</TT><CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>- : int = 17</CODE><BR>

</PRE>

When one writes f<CODE> </CODE>a<CODE> </CODE>b, there is an implicit parenthesization on
the left which makes this expression equivalent to: <TT>(</TT>f<CODE> </CODE>a<TT>)</TT><CODE> </CODE>b.<BR>
<BR>
Let's examine the application
<DIV ALIGN=center> 
<TT>(</TT><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<TT>)</TT><CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>5</CODE>
</DIV>
in detail. To compute the value of this expression, it is necessary to compute the
value of
<DIV ALIGN=center>
<TT>(</TT><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<TT>)</TT><CODE> </CODE><CODE>4</CODE>
</DIV>
which is a <EM>function expression</EM> equivalent to
<DIV ALIGN=center>
<B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE><CODE>4</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE>y
</DIV>
obtained by replacing x by <CODE>4</CODE> in <CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y.
Applying this value (which is a function) to <CODE>5</CODE> we get the
final value <CODE>3</CODE><CODE>*</CODE><CODE>4</CODE><CODE>+</CODE><CODE>5</CODE> = <CODE>1</CODE><CODE>7</CODE>:


<PRE><BR># <TT>(</TT><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<TT>)</TT><CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>- : int = 17</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Arity of a function</H4>
<A NAME="@concepts33"></A>
The number of arguments of a function is called its arity. Usage
inherited from mathematics demands that the arguments of a function be
given in parentheses after the name of the function. One writes: <I>f</I>(4,5). 
We've just seen that in Objective CAML, one more usually writes:
<I>f</I>&nbsp;4&nbsp;5. One can, of course, write a function
expression in Objective CAML which can be applied to (4,5):


<PRE><BR># <B>function</B><CODE> </CODE><TT>(</TT>x<CODE>,</CODE>y<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<CODE> </CODE>;;<BR><CODE>- : int * int -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>

But, as its type indicates, this last expression expects not two, but only
one argument: a pair of integers. Trying to pass two arguments to a
function which expects a pair or trying to pass a pair to a function which
expects two arguments results in a type error:


<PRE><BR># <TT>(</TT><B>function</B><CODE> </CODE><TT>(</TT>x<CODE>,</CODE>y<TT>)</TT><CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<TT>)</TT><CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>Characters 29-30:</CODE><BR><CODE>This expression has type int but is here used with type int * int</CODE><BR># <TT>(</TT><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<TT>)</TT><CODE> </CODE><TT>(</TT><CODE>4</CODE><CODE>,</CODE><CODE> </CODE><CODE>5</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>Characters 39-43:</CODE><BR><CODE>This expression has type int * int but is here used with type int</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Alternative syntax</H4>
<A NAME="@fonctions70"></A>
There is a more compact way of writing function expressions with several
parameters. It is a legacy of former versions of the Caml language.
Its form is as follows:


<H3> Syntax </H3> <HR>


 <B>fun</B> <I>p</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> ...<I>p</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> 
  -&gt; expr



<HR>


It allows one to omit repetitions of the <B>function</B> keyword and the arrows.
It is equivalent to the following translation: 
<DIV ALIGN=center>

 <B>function</B> <I>p</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB>  -&gt;  -&gt; function <I>p</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB>  -&gt; expr 

</DIV>


<PRE><BR># <B>fun</B><CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<CODE> </CODE>;;<BR><CODE>- : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR># <TT>(</TT><B>fun</B><CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>3</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<TT>)</TT><CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>- : int = 17</CODE><BR>

</PRE>

This form is still encountered often, in particular in the libraries provided with
the Objective CAML distribution.<BR>
<BR>

<H4> Closure</H4>
<A NAME="sec-fermeture"></A>
<A NAME="@concepts34"></A>
<A NAME="@concepts35"></A>
<A NAME="@concepts36"></A>
Objective CAML treats a function expression like any other expression and is able
to compute its value. The value returned by the computation is a
function expression and is called a closure. Every Objective CAML
expression is evaluated in an environment consisting of name-value
bindings coming from the declarations preceding the expression being
computed. A closure can be described as a triplet consisting of the name
of the formal parameter, the body of the function, and the environment of
the expression. This environment needs to be preserved because the body of
a function expression may use, in addition to the formal parameters, every other
variable declared previously. These variables are said to be ``free'' in the
function expression. Their values will be needed when the function
expression is applied.


<PRE><BR># <B>let</B><CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>3</CODE><CODE> </CODE>;;<BR><CODE>val m : int = 3</CODE><BR># <B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>m<CODE> </CODE>;;<BR><CODE>- : int -&gt; int = &lt;fun&gt;</CODE><BR># <TT>(</TT><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>m<TT>)</TT><CODE> </CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>- : int = 8</CODE><BR>

</PRE>
<BR>
<BR>
When application of a closure to an argument returns a new closure, the
latter possesses within its environment all the bindings necessary for a
future application. The subsection on the scope of variables (see page
<A HREF="book-ora015.html#subsubsec-portee">??</A>) details this notion. We will return to the
memory representation of a closure in chapter <A HREF="index.html#chap-C-Styles">4</A> (page
<A HREF="book-ora039.html#subsec-gensym">??</A>) as well as chapter <A HREF="index.html#chap-IC">12</A> (page
<A HREF="book-ora115.html#IC-fermeture">??</A>).<BR>
<BR>
The function expressions used until now are
<EM>anonymous</EM>. It is rather useful to be able to name them.<BR>
<BR>

<H4> Function value declarations</H4>
Function values are declared in the same way as other language values, by
the <B>let</B> construct.


<PRE><BR># <B>let</B><CODE> </CODE>succ<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>val succ : int -&gt; int = &lt;fun&gt;</CODE><BR># succ<CODE> </CODE><CODE>4</CODE><CODE>2</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : int = 421</CODE><BR># <B>let</B><CODE> </CODE>g<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><CODE>2</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>3</CODE><CODE>*</CODE>y<CODE> </CODE>;;<BR><CODE>val g : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR># g<CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>2</CODE>;;<BR><CODE>- : int = 8</CODE><BR>

</PRE>
<BR>
<BR>
To simplify writing, the following notation is 
allowed:<A NAME="dec-fun-equiv"></A> 


<H3> Syntax </H3> <HR>


 <B>let</B> <I>name</I> <I>p</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> ... <I>p</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB> 
 <B>=</B> <I>expr</I> 



<HR>


which is equivalent to the following form:
<DIV ALIGN=center>

 <B>let</B> <I>name</I> <B>=</B> <B>function</B> <I>p</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB>  -&gt;  -&gt; function <I>p</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB>  -&gt; expr 

</DIV><BR>
The following declarations of <TT>succ</TT> and <TT>g</TT> are equivalent
to their previous declaration.


<PRE><BR># <B>let</B><CODE> </CODE>succ<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>val succ : int -&gt; int = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>g<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>2</CODE><CODE>*</CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>3</CODE><CODE>*</CODE>y<CODE> </CODE>;;<BR><CODE>val g : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The completely functional character of Objective CAML is brought out by the
following example, in which the function <TT>h1</TT> is obtained by the
application of <TT>g</TT> to a single integer. In this case one speaks of
partial application:
<A NAME="@concepts37"></A>


<PRE><BR># <B>let</B><CODE> </CODE>h1<CODE> </CODE><CODE>=</CODE><CODE> </CODE>g<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>val h1 : int -&gt; int = &lt;fun&gt;</CODE><BR># h1<CODE> </CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>- : int = 8</CODE><BR>

</PRE>
<BR>
<BR>
One can also, starting from g, define a function h2
by fixing the value of the second parameter, y, of g:


<PRE><BR># <B>let</B><CODE> </CODE>h2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>g<CODE> </CODE>x<CODE> </CODE><CODE>2</CODE><CODE> </CODE>;;<BR><CODE>val h2 : int -&gt; int = &lt;fun&gt;</CODE><BR># h2<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : int = 8</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Declaration of infix functions</H4>
<A NAME="@concepts38"></A>
<A NAME="@concepts39"></A>
Certain functions taking two arguments can be applied in infix form. This
is the case with addition of integers. One writes <CODE>3</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>5</CODE> for the
application of <TT>+</TT> to <CODE>3</CODE> and <CODE>5</CODE>. To use the
symbol <TT>+</TT> as a regular function value, this must be syntactically
indicated by surrounding the infix symbol with parentheses. The syntax is
as follows:<BR>
<BR>


<H3> Syntax </H3> <HR>


( <TT>op</TT> )



<HR>

<BR>
<BR>
The following example defines the function <TT>succ</TT> using
<TT>(</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><TT>)</TT>. 


<PRE><BR># <TT>(</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>- : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>succ<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>val succ : int -&gt; int = &lt;fun&gt;</CODE><BR># succ<CODE> </CODE><CODE>3</CODE><CODE> </CODE>;;<BR><CODE>- : int = 4</CODE><BR>

</PRE>
<BR>
<BR>
It is also possible to define new operators. We define an operator
<TT>++</TT>, addition on pairs of integers


<PRE><BR># <B>let</B><CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>++</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>c1<CODE> </CODE>c2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>fst<CODE> </CODE>c1<TT>)</TT><CODE>+</CODE><TT>(</TT>fst<CODE> </CODE>c2<TT>)</TT><CODE>,</CODE><CODE> </CODE><TT>(</TT>snd<CODE> </CODE>c1<TT>)</TT><CODE>+</CODE><TT>(</TT>snd<CODE> </CODE>c2<TT>)</TT><CODE> </CODE>;;<BR><CODE>val ++ : int * int -&gt; int * int -&gt; int * int = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val c : int * int = 2, 3</CODE><BR># c<CODE> </CODE><CODE>++</CODE><CODE> </CODE>c<CODE> </CODE>;;<BR><CODE>- : int * int = 4, 6</CODE><BR>

</PRE>
<BR>
<BR>
There is an important limitation on the possible operators. They must
contain only <EM>symbols</EM> (such as <TT>*</TT>, <TT>+</TT>, <CODE>@</CODE>, etc. ) and
not letters or digits. Certain functions predefined as infixes are
exceptions to the rule. They are listed as follows:
<TT>or mod land lor lxor lsl lsr asr</TT>.<BR>
<BR>

<H4> Higher order functions</H4>
<A NAME="@concepts40"></A>
<A NAME="@concepts41"></A>
A function value (a closure) can be returned as a result. It can equally
well be passed as an argument to a function. Functions taking function
values as arguments or returning them as results are called higher order.


<PRE><BR># <B>let</B><CODE> </CODE>h<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE>f<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>y<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT>f<CODE> </CODE>y<TT>)</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<CODE> </CODE>;;<BR><CODE>val h : (int -&gt; int) -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>


<H3> Note </H3> <HR>

Application is implicitly parenthesized to the left, but function types are
implicitly parenthesized to the right. Thus the type of the function
<TT>h</TT> can be written<BR><DIV ALIGN=center><I>(int -&gt; int) -&gt; int -&gt; int</I>
&nbsp;or&nbsp;
<I>(int -&gt; int) -&gt; (int -&gt; int)</I></DIV>


<HR>

<BR>
<BR>
Higher order functions offer elegant possibilities for dealing with lists.
For example the function <TT>List.map</TT> can apply a function to all the
elements of a list and return the results in a list.
<A NAME="@fonctions71"></A>
<A NAME="PF-map"></A>


<PRE><BR># List.map<CODE> </CODE>;;<BR><CODE>- : ('a -&gt; 'b) -&gt; 'a list -&gt; 'b list = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>square<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>string_of_int<CODE> </CODE><TT>(</TT>x<CODE>*</CODE>x<TT>)</TT><CODE> </CODE>;;<BR><CODE>val square : int -&gt; string = &lt;fun&gt;</CODE><BR># List.map<CODE> </CODE>square<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>4</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : string list = ["1"; "4"; "9"; "16"]</CODE><BR>

</PRE>
<BR>
<BR>
As another example, the function <TT>List.for_all</TT> can find out
whether all the elements of a list satisfy a given criterion.
<A NAME="@fonctions72"></A>


<PRE><BR># List.for_all<CODE> </CODE>;;<BR><CODE>- : ('a -&gt; bool) -&gt; 'a list -&gt; bool = &lt;fun&gt;</CODE><BR># List.for_all<CODE> </CODE><TT>(</TT><B>function</B><CODE> </CODE>n<CODE> </CODE>-&gt;<CODE> </CODE>n<CODE>&lt;&gt;</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>[-</CODE><CODE>3</CODE>;<CODE> </CODE><CODE>-</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>-</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>1</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>3</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR># List.for_all<CODE> </CODE><TT>(</TT><B>function</B><CODE> </CODE>n<CODE> </CODE>-&gt;<CODE> </CODE>n<CODE>&lt;&gt;</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>[-</CODE><CODE>3</CODE>;<CODE> </CODE><CODE>-</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>0</CODE>;<CODE> </CODE><CODE>1</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>3</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : bool = false</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Scope of variables</H4><A NAME="subsubsec-portee"></A>
<A NAME="@concepts42"></A>
<A NAME="@concepts43"></A>
<A NAME="@concepts44"></A>
<A NAME="@concepts45"></A>
<A NAME="@concepts46"></A>
In order for it to be possible to evaluate an expression, all the variables
appearing therein must be defined. This is the case in particular for the
expression <TT>e</TT> in the declaration <B>let</B><CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE>e. But
since <TT>p</TT> is not yet known within this expression, this variable can
only be present if it refers to another value issued by a previous
declaration.


<PRE><BR># <B>let</B><CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE>p<CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>"-suffix"</CODE><CODE> </CODE>;;<BR><CODE>Characters 9-10:</CODE><BR><CODE>Unbound value p</CODE><BR># <B>let</B><CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"prefix"</CODE><CODE> </CODE>;;<BR><CODE>val p : string = "prefix"</CODE><BR># <B>let</B><CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE>p<CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>"-suffix"</CODE><CODE> </CODE>;;<BR><CODE>val p : string = "prefix-suffix"</CODE><BR>

</PRE>
<BR>
<BR>
In Objective CAML, variables are statically bound. The environment used to
execute the application of a closure is the one in effect at the moment of
its declaration (static scope) and not the one in effect at the moment of
application (dynamic scope).<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val p : int = 10</CODE><BR># <B>let</B><CODE> </CODE>k<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>x<CODE>,</CODE><CODE> </CODE>p<CODE>,</CODE><CODE> </CODE>x<CODE>+</CODE>p<TT>)</TT><CODE> </CODE>;;<BR><CODE>val k : int -&gt; int * int * int = &lt;fun&gt;</CODE><BR># k<CODE> </CODE>p<CODE> </CODE>;;<BR><CODE>- : int * int * int = 10, 10, 20</CODE><BR># <B>let</B><CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val p : int = 1000</CODE><BR># k<CODE> </CODE>p<CODE> </CODE>;;<BR><CODE>- : int * int * int = 1000, 10, 1010</CODE><BR>

</PRE>

The function <TT>k</TT> contains a free variable: <TT>p</TT>. Since the latter
is defined in the global environment, the definition of <TT>k</TT> is
legal. The binding between the name <TT>p</TT> and the value <CODE>1</CODE><CODE>0</CODE>
in the environment of the closure <TT>k</TT> is static, i.e., does not
depend on the most recent definition of <TT>p</TT>.<BR>
<BR>

<H4> Recursive declarations</H4>
<A NAME="@concepts47"></A>
<A NAME="@concepts48"></A>
<A NAME="@fonctions73"></A>A variable declaration is called recursive if it
uses its own identifier in its definition. This facility is used
mainly for functions, notably to simulate a definition by recurrence. We
have just seen that the <B>let</B> declaration does not support this.
To declare a recursive function we will use a dedicated syntactic construct.


<H3> Syntax </H3> <HR>


 <B>let rec</B> <I>name</I> <B>=</B> <I>expr</I> <B>;;</B>



<HR>


We can equally well use the syntactic facility for defining function values
while indicating the function parameters:


<H3> Syntax </H3> <HR>


 <B>let rec</B> <I>name</I> <I>p</I><SUB><I><FONT SIZE=2>1</FONT></I></SUB> ...<I>p</I><SUB><I><FONT SIZE=2><I>n</I></FONT></I></SUB>
 <B>=</B> <I>expr</I> <B>;;</B> 



<HR>

<BR>
<BR>
By way of example, here is the function <TT>sigma</TT> which computes the
sum of the (non-negative) integers between <CODE>0</CODE> and the
value of its argument, inclusive. 


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>sigma<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>if</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>then</B><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>else</B><CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>sigma<CODE> </CODE><TT>(</TT>x<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val sigma : int -&gt; int = &lt;fun&gt;</CODE><BR># sigma<CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : int = 55</CODE><BR>

</PRE>

It may be noted that this function does not terminate if its argument is
strictly negative.<BR>
<BR>
A recursive value is in general a function. The compiler rejects
some recursive declarations whose values are not functions:


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>Characters 13-18:</CODE><BR><CODE>This kind of expression is not allowed as right-hand side of `let rec'</CODE><BR>

</PRE>

We will see however that in certain cases such declarations are allowed (see 
page <A HREF="book-ora016.html#decl_rec">??</A>).<BR>
<BR>
<A NAME="@concepts49"></A>
The <B>let rec</B> declaration may be combined with the
<B>and</B> construction for simultaneous declarations. In this case, all 
the functions defined at the same level are known within the bodies of each 
of the others. This permits, among other things, the declaration of 
mutually recursive functions.


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>even<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>n<CODE>&lt;&gt;</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>n<CODE>=</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><B>or</B><CODE> </CODE><TT>(</TT>odd<CODE> </CODE><TT>(</TT>n<CODE>-</CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><TT>)</TT><BR><CODE> </CODE><B>and</B><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>odd<CODE> </CODE><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>n<CODE>&lt;&gt;</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><CODE>&amp;&amp;</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>n<CODE>=</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><B>or</B><CODE> </CODE><TT>(</TT>even<CODE> </CODE><TT>(</TT>n<CODE>-</CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><TT>)</TT><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>;;<BR><CODE>val even : int -&gt; bool = &lt;fun&gt;</CODE><BR><CODE>val odd : int -&gt; bool = &lt;fun&gt;</CODE><BR># even<CODE> </CODE><CODE>4</CODE><CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR># odd<CODE> </CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR>

</PRE>
<BR>
<BR>
In the same way, local declarations can be recursive. This new definition
of <TT>sigma</TT> tests the validity of its argument before carrying out
the computation of the sum defined by a local function <TT>sigma_rec</TT>.


<PRE><BR># <B>let</B><CODE> </CODE>sigma<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>sigma_rec<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>then</B><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>else</B><CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>sigma_rec<CODE> </CODE><TT>(</TT>x<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE><TT>(</TT>x<CODE>&lt;</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><CODE>"error: negative argument"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>"sigma = "</CODE><CODE> </CODE><CODE>^</CODE><CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE><TT>(</TT>sigma_rec<CODE> </CODE>x<TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>val sigma : int -&gt; string = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>


<H3> Note </H3> <HR>

The need to give a return value of the same type, whether the argument is
negative or not, has forced us to give the result in the form of a
character string. Indeed, what value should be returned by <TT>sigma</TT> when its
argument is negative? We will see the proper way to manage this problem,
using exceptions (see page <A HREF="book-ora017.html#sec-exceptions">??</A>). 


<HR>

<BR>
<BR>
<A NAME="toc12"></A>
<H3> Polymorphism and type constraints</H3>
<A NAME="subsec-poly"></A>
<A NAME="@concepts50"></A>
<A NAME="@concepts51"></A>
<A NAME="@concepts52"></A>
Some functions execute the same code for arguments having different types.
For example, creation of a pair from two values doesn't require 
different functions for each type known to the 
system<A NAME="text7" HREF="book-ora023.html#note7"><SUP><FONT SIZE=2>5</FONT></SUP></A>. In the same way, the function to access the first field of a pair doesn't
have to be differentiated according to the type of the value of this first
field.


<PRE><BR># <B>let</B><CODE> </CODE>make_pair<CODE> </CODE>a<CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>a<CODE>,</CODE>b<TT>)</TT><CODE> </CODE>;;<BR><CODE>val make_pair : 'a -&gt; 'b -&gt; 'a * 'b = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE>make_pair<CODE> </CODE><CODE>"paper"</CODE><CODE> </CODE><CODE>4</CODE><CODE>5</CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>val p : string * int = "paper", 451</CODE><BR># <B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>make_pair<CODE> </CODE><CODE>'B'</CODE><CODE> </CODE><CODE>6</CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>val a : char * int = 'B', 65</CODE><BR># fst<CODE> </CODE>p<CODE> </CODE>;;<BR><CODE>- : string = "paper"</CODE><BR># fst<CODE> </CODE>a<CODE> </CODE>;;<BR><CODE>- : char = 'B'</CODE><BR>

</PRE>
<BR>
<BR>
Functions are called polymorphic if their return value or one of their
parameters is of a type which need not be specified. The type synthesizer
contained in the Objective CAML compiler finds the most general type for each
expression. In this case, Objective CAML uses variables, here <I>'a</I> and
<I>'b</I>, to designate these general types. These variables are
instantiated to the type of the argument during application of the
function.<BR>
<BR>
With Objective CAML's polymorphic functions, we get the advantages of being
able to write generic code usable for values of every type, while still
preserving the execution safety of static typing. Indeed, although
<TT>make_pair</TT> is polymorphic, the value created by
<TT>(</TT>make_pair<CODE> </CODE><CODE>'B'</CODE><CODE> </CODE><CODE>6</CODE><CODE>5</CODE><TT>)</TT> has a well-specified type which is different
from that of <TT>(</TT>make_pair<CODE> </CODE><CODE>"paper"</CODE><CODE> </CODE><CODE>4</CODE><CODE>5</CODE><CODE>1</CODE><TT>)</TT>. Moreover, type
verification is carried out on compilation, so the generality of the code
does not hamper the efficiency of the program.<BR>
<BR>

<H4> Examples of polymorphic functions and values</H4>
The following examples of polymorphic functions have functional parameters
whose type is parameterized.<BR>
<BR>
The <TT>app</TT> function applies a function to an argument.


<PRE><BR># <B>let</B><CODE> </CODE>app<CODE> </CODE><CODE>=</CODE><CODE> </CODE><B>function</B><CODE> </CODE>f<CODE> </CODE>-&gt;<CODE> </CODE><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>f<CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val app : ('a -&gt; 'b) -&gt; 'a -&gt; 'b = &lt;fun&gt;</CODE><BR>

</PRE>

So it can be applied to the function <TT>odd</TT> defined previously: 


<PRE><BR># app<CODE> </CODE>odd<CODE> </CODE><CODE>2</CODE>;;<BR><CODE>- : bool = false</CODE><BR>

</PRE>
<BR>
<BR>
The identity function (<TT>id</TT> ) takes a parameter and returns it as is.


<PRE><BR># <B>let</B><CODE> </CODE>id<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE>;;<BR><CODE>val id : 'a -&gt; 'a = &lt;fun&gt;</CODE><BR># app<CODE> </CODE>id<CODE> </CODE><CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>- : int = 1</CODE><BR>

</PRE>
<BR>
<BR>
The <TT>compose</TT> function takes two functions and another value and
composes the application of these two functions to this value.


<PRE><BR># <B>let</B><CODE> </CODE>compose<CODE> </CODE>f<CODE> </CODE>g<CODE> </CODE><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>f<CODE> </CODE><TT>(</TT>g<CODE> </CODE>x<TT>)</TT><CODE> </CODE>;;<BR><CODE>val compose : ('a -&gt; 'b) -&gt; ('c -&gt; 'a) -&gt; 'c -&gt; 'b = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>add1<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE>+</CODE><CODE>1</CODE><CODE> </CODE><B>and</B><CODE> </CODE>mul5<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE>*</CODE><CODE>5</CODE><CODE> </CODE><B>in</B><CODE> </CODE>compose<CODE> </CODE><CODE> </CODE>mul5<CODE> </CODE>add1<CODE> </CODE><CODE> </CODE><CODE>9</CODE><CODE> </CODE>;;<BR><CODE>- : int = 50</CODE><BR>

</PRE>

It can be seen that the result of <TT>g</TT> must be of the same type as
the argument of <TT>f</TT>.<BR>
<BR>
Values other than functions can be polymorphic as well. For example, this is
the case for the empty list:


<PRE><BR># <B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>[]<CODE> </CODE>;;<BR><CODE>val l : 'a list = []</CODE><BR>

</PRE>
<BR>
<BR>
The following example demonstrates that type synthesis indeed arises from
resolution of the constraints coming from function application and not from the value
obtained upon execution.


<PRE><BR># <B>let</B><CODE> </CODE>t<CODE> </CODE><CODE>=</CODE><CODE> </CODE>List.tl<CODE> </CODE><CODE>[</CODE><CODE>2</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>val t : int list = []</CODE><BR>

</PRE>

The type of <TT>List.tl</TT> is <I>'a list -&gt; 'a list</I>, so this
function applied to a list of integers returns a list of integers. The
fact that upon execution it is the empty list which is obtained doesn't
change its type at all.<BR>
<BR>
<A NAME="@concepts53"></A>
Objective CAML generates parameterized types for every function which doesn't use
the form of its arguments. This polymorphism is called
parametric polymorphism<A NAME="text8" HREF="book-ora023.html#note8"><SUP><FONT SIZE=2>6</FONT></SUP></A>. <BR>
<BR>

<H4> Type constraint</H4>
<A NAME="@concepts54"></A>
As the Caml type synthesizer generates the most general type, it may be
useful or necessary to specify the type of an expression.<BR>
<BR>
The syntactic form of a type constraint is as follows:
<A NAME="@fonctions74"></A>


<H3> Syntax </H3> <HR>


<B>(</B> <I>expr</I> <B>:</B> <I>t</I> <B>)</B>



<HR>


When it runs into such a constraint, the type synthesizer will take it into
account while constructing the type of the expression. Using type
constraints lets one:
<UL>
<LI>
 make the type of the parameters of a function visible;

<LI> forbid the use of a function outside its intended context;

<LI> specify the type of an expression, which will be particularly useful
for mutable values (see page <A HREF="book-ora026.html#sec-mutables">??</A>). 
</UL>The following examples demonstrate the use of such type constraints


<PRE><BR># <B>let</B><CODE> </CODE>add<CODE> </CODE><TT>(</TT>x<CODE>:</CODE>int<TT>)</TT><CODE> </CODE><TT>(</TT>y<CODE>:</CODE>int<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE> </CODE><CODE>+</CODE><CODE> </CODE>y<CODE> </CODE>;;<BR><CODE>val add : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>make_pair_int<CODE> </CODE><TT>(</TT>x<CODE>:</CODE>int<TT>)</TT><CODE> </CODE><TT>(</TT>y<CODE>:</CODE>int<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>x<CODE>,</CODE>y;;<BR><CODE>val make_pair_int : int -&gt; int -&gt; int * int = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>compose_fn_int<CODE> </CODE><TT>(</TT>f<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>int<TT>)</TT><CODE> </CODE><TT>(</TT>g<CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>-&gt;<CODE> </CODE>int<TT>)</TT><CODE> </CODE><TT>(</TT>x<CODE>:</CODE>int<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>compose<CODE> </CODE>f<CODE> </CODE>g<CODE> </CODE><CODE> </CODE>x;;<BR><CODE>val compose_fn_int : (int -&gt; int) -&gt; (int -&gt; int) -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>nil<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>[]<CODE> </CODE><CODE>:</CODE><CODE> </CODE>string<CODE> </CODE>list<TT>)</TT>;;<BR><CODE>val nil : string list = []</CODE><BR># <CODE>'H'</CODE>::nil;;<BR><CODE>Characters 5-8:</CODE><BR><CODE>This expression has type string list but is here used with type char list</CODE><BR>

</PRE>
<BR>
<BR>
Restricting polymorphism this way lets us control the type of an expression
better by constraining the polymorphism of the type deduced by the system.
Any defined type whatsoever may be used, including ones containing type
variables, as the following example shows:


<PRE><BR># <B>let</B><CODE> </CODE>llnil<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>[]<CODE> </CODE><CODE>:</CODE><CODE> </CODE><I>'a</I><CODE> </CODE>list<CODE> </CODE>list<TT>)</TT><CODE> </CODE>;;<BR><CODE>val llnil : 'a list list = []</CODE><BR># <CODE>[</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE><CODE>]::</CODE><CODE> </CODE>llnil<CODE> </CODE>;;<BR><CODE>- : int list list = [[1; 2; 3]]</CODE><BR>

</PRE>

The symbol <TT>llnil</TT> is a list of lists of any type whatsoever.<BR>
<BR>
Here we are dealing with constraints, and not replacing Objective CAML's type
synthesis with explicit typing. In particular, one cannot
generalize types beyond what inference permits.


<PRE><BR># <B>let</B><CODE> </CODE>add_general<CODE> </CODE><TT>(</TT>x<CODE>:</CODE><I>'a</I><TT>)</TT><CODE> </CODE><TT>(</TT>y<CODE>:</CODE><I>'b</I><TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE>add<CODE> </CODE>x<CODE> </CODE>y<CODE> </CODE>;;<BR><CODE>val add_general : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
Type constraints will be used in module interfaces (<A HREF="index.html#chap-modules">14</A>)
as well as in class declarations (<A HREF="index.html#chap-POO">15</A>).<BR>
<BR>
<A NAME="toc13"></A>
<H3> Examples</H3><A NAME="sub-ex-liste"></A>
In this section we will give several somewhat elaborate examples of
functions. Most of these functions are predefined in Objective CAML. We will
redefine them for the sake of ``pedagogy''.<BR>
<BR>
Here, the test for the terminal case of recursive functions is implemented
by a conditional. 
Hence a programming style closer to Lisp. We will see
how to give a more ML character to these definitions when we present
another way of defining functions by case (see page
<A HREF="book-ora016.html#subsec-filtrage">??</A>). <BR>
<BR>

<H4> Length of a list</H4>Let's start with the function <TT>null</TT> which
tests whether a list is empty.


<PRE><BR># <B>let</B><CODE> </CODE>null<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE>[]<TT>)</TT><CODE> </CODE>;;<BR><CODE>val null : 'a list -&gt; bool = &lt;fun&gt;</CODE><BR>

</PRE>

Next, we define the function <TT>size</TT> to compute the length of a list
(i.e., the number of its elements).
<A NAME="fonc-size"></A>


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>size<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>null<CODE> </CODE>l<CODE> </CODE><B>then</B><CODE> </CODE><CODE>0</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>+</CODE><CODE> </CODE><TT>(</TT>size<CODE> </CODE><TT>(</TT>List.tl<CODE> </CODE>l<TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>val size : 'a list -&gt; int = &lt;fun&gt;</CODE><BR># size<CODE> </CODE>[]<CODE> </CODE>;;<BR><CODE>- : int = 0</CODE><BR># size<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>1</CODE><CODE>8</CODE>;<CODE>2</CODE><CODE>2</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int = 4</CODE><BR>

</PRE>

The function <TT>size</TT> tests whether the list argument is empty.
If so it returns <TT>0</TT>, if not it returns <TT>1</TT> plus the value
resulting from computing the length of the tail of the list.<BR>
<BR>

<H4> Iteration of composition</H4>
The expression iterate<CODE> </CODE>n<CODE> </CODE>f computes the value <TT>f</TT>
iterated <I>n</I> times. 


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>iterate<CODE> </CODE>n<CODE> </CODE>f<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>then</B><CODE> </CODE><TT>(</TT><B>function</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>x<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>compose<CODE> </CODE>f<CODE> </CODE><TT>(</TT>iterate<CODE> </CODE><TT>(</TT>n<CODE>-</CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>f<TT>)</TT><CODE> </CODE>;;<BR><CODE>val iterate : int -&gt; ('a -&gt; 'a) -&gt; 'a -&gt; 'a = &lt;fun&gt;</CODE><BR>

</PRE>

The <TT>iterate</TT> function tests whether n is 0, if yes it returns the
identity function, if not it composes <TT>f</TT> with
the iteration of <TT>f</TT> <TT>n-1</TT> times.<BR>
<BR>
Using <TT>iterate</TT>, one can define exponentiation as iteration of
multiplication.


<PRE>
<CODE> </CODE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>power<CODE> </CODE>i<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>i_times<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>i<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>iterate<CODE> </CODE>n<CODE> </CODE>i_times<CODE> </CODE><CODE>1</CODE><CODE> </CODE>;;<BR><CODE>val power : int -&gt; int -&gt; int = &lt;fun&gt;</CODE><BR># power<CODE> </CODE><CODE>2</CODE><CODE> </CODE><CODE>8</CODE><CODE> </CODE>;;<BR><CODE>- : int = 256</CODE><BR>

</PRE>

The <TT>power</TT> function iterates <I>n</I> times the function expression
<TT>i_times</TT>, then applies this result to 1, which does indeed
compute the <I>n</I>th power of an integer. <BR>
<BR>

<H4> Multiplication table</H4>
We want to write a function multab which computes the multiplication
table of an integer passed as an argument.<BR>
<BR>
First we define the function <TT>apply_fun_list</TT> such that, if
f_list is a list of functions, apply_fun_list<CODE> </CODE>x<CODE> </CODE>f_list
returns the list of results of applying each element of
f_list to x.


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>apply_fun_list<CODE> </CODE>x<CODE> </CODE>f_list<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>null<CODE> </CODE>f_list<CODE> </CODE><B>then</B><CODE> </CODE>[]<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><TT>(</TT><TT>(</TT>List.hd<CODE> </CODE>f_list<TT>)</TT><CODE> </CODE>x<TT>)</TT>::<TT>(</TT>apply_fun_list<CODE> </CODE>x<CODE> </CODE><TT>(</TT>List.tl<CODE> </CODE>f_list<TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>val apply_fun_list : 'a -&gt; ('a -&gt; 'b) list -&gt; 'b list = &lt;fun&gt;</CODE><BR># apply_fun_list<CODE> </CODE><CODE>1</CODE><CODE> </CODE><CODE>[</CODE><TT>(</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE><CODE>1</CODE>;<TT>(</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE><CODE>2</CODE>;<TT>(</TT><CODE> </CODE><CODE>+</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE><CODE>3</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int list = [2; 3; 4]</CODE><BR>

</PRE>
<BR>
<BR>
The function mk_mult_fun_list returns the list of
functions multiplying their argument by i,
for i varying from <CODE>0</CODE> to n.


<PRE><BR># <B>let</B><CODE> </CODE>mk_mult_fun_list<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>mmfl_aux<CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>p<CODE> </CODE><CODE>=</CODE><CODE> </CODE>n<CODE> </CODE><B>then</B><CODE> </CODE><CODE>[</CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>n<CODE> </CODE><CODE>]</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE><TT>(</TT><TT>(</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE>p<TT>)</TT><CODE> </CODE>::<CODE> </CODE><TT>(</TT>mmfl_aux<CODE> </CODE><TT>(</TT>p<CODE>+</CODE><CODE>1</CODE><TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE> </CODE><TT>(</TT>mmfl_aux<CODE> </CODE><CODE>1</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val mk_mult_fun_list : int -&gt; (int -&gt; int) list = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
We obtain the multiplication table of 7 by:


<PRE><BR># <B>let</B><CODE> </CODE>multab<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>apply_fun_list<CODE> </CODE>n<CODE> </CODE><TT>(</TT>mk_mult_fun_list<CODE> </CODE><CODE>1</CODE><CODE>0</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val multab : int -&gt; int list = &lt;fun&gt;</CODE><BR># multab<CODE> </CODE><CODE>7</CODE><CODE> </CODE>;;<BR><CODE>- : int list = [7; 14; 21; 28; 35; 42; 49; 56; 63; 70]</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Iteration over lists</H4>
<A NAME="fun-fold-left"></A>
The function call fold_left<CODE> </CODE>f<CODE> </CODE>a<CODE> </CODE><CODE>[</CODE>e1;<CODE> </CODE>e2;<CODE> </CODE><CODE>...</CODE><CODE> </CODE>;<CODE> </CODE>en<CODE>]</CODE>
returns f<CODE> </CODE><CODE>...</CODE><CODE> </CODE><TT>(</TT>f<CODE> </CODE><TT>(</TT>f<CODE> </CODE>a<CODE> </CODE>e1<TT>)</TT><CODE> </CODE>e2<TT>)</TT><CODE> </CODE><CODE>...</CODE><CODE> </CODE>en. So there are <I>n</I>
applications. 


<PRE><BR># <B>let</B><CODE> </CODE><B>rec</B><CODE> </CODE>fold_left<CODE> </CODE>f<CODE> </CODE>a<CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>null<CODE> </CODE>l<CODE> </CODE><B>then</B><CODE> </CODE>a<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>else</B><CODE> </CODE>fold_left<CODE> </CODE>f<CODE> </CODE><TT>(</TT><CODE> </CODE>f<CODE> </CODE>a<CODE> </CODE><TT>(</TT>List.hd<CODE> </CODE>l<TT>)</TT><TT>)</TT><CODE> </CODE><TT>(</TT>List.tl<CODE> </CODE>l<TT>)</TT><CODE> </CODE>;;<BR><CODE>val fold_left : ('a -&gt; 'b -&gt; 'a) -&gt; 'a -&gt; 'b list -&gt; 'a = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The function <TT>fold_left</TT> permits the compact definition of a
function to compute the sum of the elements of a list of integers:


<PRE><BR># <B>let</B><CODE> </CODE>sum_list<CODE> </CODE><CODE>=</CODE><CODE> </CODE>fold_left<CODE> </CODE><TT>(</TT><CODE>+</CODE><TT>)</TT><CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>val sum_list : int list -&gt; int = &lt;fun&gt;</CODE><BR># sum_list<CODE> </CODE><CODE>[</CODE><CODE>2</CODE>;<CODE>4</CODE>;<CODE>7</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int = 13</CODE><BR>

</PRE>
<BR>
<BR>
Or else, the concatenation of the elements of a list of strings:


<PRE><BR># <B>let</B><CODE> </CODE>concat_list<CODE> </CODE><CODE>=</CODE><CODE> </CODE>fold_left<CODE> </CODE><TT>(</TT><CODE>^</CODE><TT>)</TT><CODE> </CODE><CODE>""</CODE><CODE> </CODE>;;<BR><CODE>val concat_list : string list -&gt; string = &lt;fun&gt;</CODE><BR># concat_list<CODE> </CODE><CODE>[</CODE><CODE>"Hello "</CODE>;<CODE> </CODE><CODE>"world"</CODE><CODE> </CODE>;<CODE> </CODE><CODE>"!"</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : string = "Hello world!"</CODE><BR>

</PRE>
<BR>
<BR>
<HR>
<A HREF="book-ora014.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora016.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
